﻿using System.Collections;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Interactivity;

namespace TMLibrary
{
    [Description("Changes to a visual state")]
    public class GoToStateAction : TriggerAction<FrameworkElement>
    {
        [Category("Common Properties"), Description("Gets or sets the name of the state to change to"), CustomPropertyValueEditor(CustomPropertyValueEditor.StateName)]
        public string StateName
        {
            get;
            set;
        }

        public static readonly DependencyProperty UseTransitionsProperty = DependencyProperty.Register("UseTransitions", typeof(bool), typeof(GoToStateAction), new PropertyMetadata(true));
        [Category("Common Properties"), Description("Gets or sets a value specifying whether to animate the transition")]
        public bool UseTransitions
        {
            get { return (bool)this.GetValue(UseTransitionsProperty); }
            set { this.SetValue(UseTransitionsProperty, value); }
        }

        protected override void OnAttached()
        {
            base.OnAttached();
        }

        protected override void Invoke(object parameter)
        {
            AssociatedObject.Dispatcher.BeginInvoke(delegate()
            {
				VisualStateManager.GoToState(FindTargetElement(AssociatedObject) as Control, StateName, UseTransitions);
            });
        }

        internal static FrameworkElement FindTargetElement(FrameworkElement element)
        {
            while (element != null)
            {
                IList vsgs = VisualStateManager.GetVisualStateGroups(element);
                if (vsgs != null && vsgs.Count > 0)
                {
                    Control control = element.Parent as Control;
                    if (control != null)
                        return control;
                    return element;
                }
                element = element.Parent as FrameworkElement;
            }
            return null;
        }
    }
}